import pygame
import random
from src.base_game import BaseGame


class SnakeGame(BaseGame):
    """Simple Snake game implementation"""
    
    def __init__(self, screen: pygame.Surface, resource_manager):
        super().__init__("Snake", screen, resource_manager)
        
    def initialize(self) -> None:
        """Initialize Snake game"""
        self.screen_width = self.screen.get_width()
        self.screen_height = self.screen.get_height()
        
        # Grid settings
        self.grid_size = 20
        self.grid_width = self.screen_width // self.grid_size
        self.grid_height = self.screen_height // self.grid_size
        
        # Snake
        self.snake = [(self.grid_width // 2, self.grid_height // 2)]
        self.direction = (1, 0)  # Start moving right
        
        # Food
        self.food = self.generate_food()
        
        # Game state
        self.game_over = False
        self.score = 0
        
        # Movement timer
        self.move_timer = 0
        self.move_delay = 0.15  # Move every 150ms
        
        # Colors
        self.black = (0, 0, 0)
        self.green = (0, 255, 0)
        self.red = (255, 0, 0)
        self.white = (255, 255, 255)
        
        # Font
        self.font = pygame.font.Font(None, 36)
        
    def generate_food(self) -> tuple:
        """Generate food at random position not on snake"""
        while True:
            food_pos = (
                random.randint(0, self.grid_width - 1),
                random.randint(0, self.grid_height - 1)
            )
            if food_pos not in self.snake:
                return food_pos
                
    def handle_event(self, event: pygame.event.Event) -> None:
        """Handle Snake-specific events"""
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP and self.direction != (0, 1):
                self.direction = (0, -1)
            elif event.key == pygame.K_DOWN and self.direction != (0, -1):
                self.direction = (0, 1)
            elif event.key == pygame.K_LEFT and self.direction != (1, 0):
                self.direction = (-1, 0)
            elif event.key == pygame.K_RIGHT and self.direction != (-1, 0):
                self.direction = (1, 0)
            elif event.key == pygame.K_r and self.game_over:
                self.restart_game()
                
    def restart_game(self) -> None:
        """Restart the game"""
        self.snake = [(self.grid_width // 2, self.grid_height // 2)]
        self.direction = (1, 0)
        self.food = self.generate_food()
        self.game_over = False
        self.score = 0
        self.move_timer = 0
        
    def update(self, dt: float) -> None:
        """Update Snake game logic"""
        if self.game_over:
            return
            
        self.move_timer += dt
        
        if self.move_timer >= self.move_delay:
            self.move_timer = 0
            
            # Move snake
            head_x, head_y = self.snake[0]
            new_head = (head_x + self.direction[0], head_y + self.direction[1])
            
            # Check collision with walls
            if (new_head[0] < 0 or new_head[0] >= self.grid_width or
                new_head[1] < 0 or new_head[1] >= self.grid_height):
                self.game_over = True
                return
                
            # Check collision with self
            if new_head in self.snake:
                self.game_over = True
                return
                
            # Add new head
            self.snake.insert(0, new_head)
            
            # Check if food eaten
            if new_head == self.food:
                self.score += 1
                self.food = self.generate_food()
                # Increase speed slightly
                self.move_delay = max(0.05, self.move_delay - 0.005)
            else:
                # Remove tail if no food eaten
                self.snake.pop()
                
    def render(self) -> None:
        """Render Snake game"""
        # Clear screen
        self.screen.fill(self.black)
        
        # Draw snake
        for segment in self.snake:
            rect = pygame.Rect(
                segment[0] * self.grid_size,
                segment[1] * self.grid_size,
                self.grid_size,
                self.grid_size
            )
            pygame.draw.rect(self.screen, self.green, rect)
            pygame.draw.rect(self.screen, self.white, rect, 1)
            
        # Draw food
        food_rect = pygame.Rect(
            self.food[0] * self.grid_size,
            self.food[1] * self.grid_size,
            self.grid_size,
            self.grid_size
        )
        pygame.draw.rect(self.screen, self.red, food_rect)
        
        # Draw score
        score_text = self.font.render(f"Score: {self.score}", True, self.white)
        self.screen.blit(score_text, (10, 10))
        
        # Draw instructions
        if not self.game_over:
            instruction_text = self.font.render("Arrow keys to move, ESC to quit", True, self.white)
            self.screen.blit(instruction_text, (10, self.screen_height - 40))
        else:
            game_over_text = self.font.render("GAME OVER! Press R to restart", True, self.white)
            text_rect = game_over_text.get_rect(center=(self.screen_width // 2, self.screen_height // 2))
            self.screen.blit(game_over_text, text_rect)